﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using ShevaEngine.Core.Modules.Audio;
using ShevaEngine.Core.Modules.Input;
using ShevaEngine.Core.Modules.Materials;
using ShevaEngine.Core.Modules.ParticleSystems;
using ShevaEngine2.Modules.Animations;

namespace ShevaEngine.Core
{
    /// <summary>
    /// Base Sheva Engine 2 class.
    /// </summary>
    public class ShevaEngine : Game
    {
        /// <summary>Singleton.</summary>
        public static readonly ShevaEngine Instance = new ShevaEngine(ShevaEngineSettings.Instance);


        /// <summary>Graphics device manager.</summary>
        private GraphicsDeviceManager GraphicsDeviceManager;
        /// <summary>Sprite batch.</summary>
        public SpriteBatch SpriteBatch;

        /// <summary>Engine initializated event.</summary>
        public event EventHandler EngineInitializated;

        /// <summary>
        /// Constructor.
        /// </summary>
        public ShevaEngine(ShevaEngineSettings settings)
            : base()
        {
            this.Window.Title = "Sheva Engine 2.0";

            this.Content.RootDirectory = "Content";            

            this.GraphicsDeviceManager = new GraphicsDeviceManager(this);
            this.GraphicsDeviceManager.PreparingDeviceSettings += this.graphics_PreparingDeviceSettings;            
            this.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = false;                                   

            this.Window.AllowUserResizing = true;

            this.IsFixedTimeStep = false;
            this.IsMouseVisible = true;

            if (settings.DynamicResolution)
            {
                this.GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
                this.GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
            }
            else
            {
                this.GraphicsDeviceManager.PreferredBackBufferWidth = settings.BackbufferWidth;
                this.GraphicsDeviceManager.PreferredBackBufferHeight = settings.BackbufferHeight;
            }

            this.Components.Add(new GamerServicesComponent(this));
        }

        /// <summary>
        /// Perf HUD support.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            foreach (GraphicsAdapter curAdapter in GraphicsAdapter.Adapters)
            {
                if (curAdapter.Description.Contains("PerfHUD"))
                {
                    e.GraphicsDeviceInformation.Adapter = curAdapter;
                    GraphicsAdapter.UseReferenceDevice = true;
                    
                    break;
                }
            }
            return;
        }

        /// <summary>
        /// Load content.
        /// </summary>
        protected override void LoadContent()
        {
            base.LoadContent();            

            this.SpriteBatch = new SpriteBatch(this.GraphicsDevice);


            if (this.EngineInitializated != null)
                this.EngineInitializated(this, null);
        }

        /// <summary>
        /// Override method Draw().
        /// </summary>
        /// <param name="gameTime"></param>
        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            TextureManager.Instance.Update(gameTime);

            ShevaGameModule.Instance.Draw();            
        }     

        /// <summary>
        /// Override method Update().
        /// </summary>
        /// <param name="gameTime"></param>
        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            AnimationsManager.Instance.Update(gameTime);
            ParticleSystemManager.Instance.Update(gameTime);
            InputManager.Instance.Update(gameTime);
            AudioSystem.Instance.Update(gameTime);
            ShevaGameModule.Instance.Update(gameTime);
        }       
    }
}
